/* eslint-disable compat/compat */
import { useEffect, forwardRef, useImperativeHandle } from "react";
import type { TableProps } from "antd";
import { Table } from "antd";
import TableHeader from "./components/table-header";
import TableSearch from "./components/table-search";
import { CustomColumns } from "./components/coustom-columns";
import { useTable } from "./use-table";
import type { Dayjs } from "dayjs";
import { useStyle } from "./use-style";
import type { TableRowSelection } from "antd/es/table/interface";

type ColumnsType<T extends object = object> = TableProps<T>["columns"];

type TableComponents<T extends object = object> = TableProps<T>["components"];

// 让 ProTable 支持动态 DataType，可以将 ProTableProps 泛型化
// 并将 DataType 相关类型参数化

// 泛型化 ProTableProps 和相关类型
export type ProTableColumns<T extends object = any> = ColumnsType<T>;

type Generic = string;
type GenericFn = (value: Dayjs) => string;
export type FormatType =
	| Generic
	| GenericFn
	| Array<Generic | GenericFn>
	| {
			format: string;
			type?: "mask";
	  };

export type OptionItem = {
	label: string;
	value: string | number;
};
// 搜索表单类型
export type SearchFormItem = {
	label?: string; // 搜索表单标签
	name: string; // 搜索表单key
	type?: string; // 搜索表单类型
	placeholder?: string; // 搜索表单占位符
	initialValue?: string | string[] | number | number[] | Date | Date[] | any; // 搜索表单初始值
	hidden?: boolean; // 搜索表单是否隐藏
	span?: number; // 搜索表单列宽
	render?: (value?: any) => React.ReactNode; // 搜索表单渲染, 用于自定义搜索表单
	picker?: "date" | "week" | "month" | "quarter" | "year"; // 日期选择器类型
	format?: FormatType; // 日期选择器格式
	rangeName?: string[]; // 范围的key
	showTime?: boolean; // 日期组件是否显示时分秒
	options?: OptionItem[]; // 下拉框选项
	disabled?: boolean; // 搜索表单是否禁用
	allowClear?: boolean; // 搜索表单是否允许清空
	onChange?: (value: any) => void; // 搜索表单变化回调
	value?: any; // 搜索表单值
	isDateRange?: boolean; // 是否是范围选择
};

// 展开行配置
export type Expandable = {
	childrenColumnName?: string; // 指定树形结构的列名
	columnWidth?: number; // 展开行宽度
	defaultExpandAllRows?: boolean; // 初始时，是否展开所有行
	defaultExpandedRowKeys?: string[]; // 默认展开的行
	expandedRowClassName?: (record: any, index: number) => string; // 展开行样式
	expandedRowRender?: (record: any, index: number, indent: number, expanded: boolean) => React.ReactNode; // 额外的展开行
	expandRowByClick?: boolean; // 是否点击行展开
	fixed?: "left" | "right"; // 控制展开图标是否固定，可选 true 'left' 'right'
};

export type OnRowType<T extends object = any> = TableProps<T>["onRow"];

// 表格组件的 props 类型
export interface ProTableProps<T extends object = any> {
	columns: ProTableColumns<T>; // 表格列配置
	api?: (params?: any) => Promise<any>; // 表格数据请求方法
	dataSource?: T[]; // 表格数据,父组件传入的数据
	isPagination?: boolean; // 是否开启分页
	rowKey?: (record: T) => string | number; // 行唯一标识
	rowSelection?: TableRowSelection<T>; // 行选择
	isRowSelection?: boolean; // 是否开启行选择
	callback?: (props: { data: any; selectedRowKeys: React.Key[]; searchParams: any }) => void; // 回调函数
	tableHeaderRightSlot?: React.ReactNode; // 表格头部
	title?: string; // 表格标题
	searchForm?: SearchFormItem[]; // 搜索表单数组数据
	formItemLayout?: any; // 搜索表单布局
	tableRenderStatistics?: (params?: any) => React.ReactNode; // 表格统计渲染
	tableSize?: "small" | "middle" | "large"; // 表格大小,默认large，small为小表格，middle为中表格，large为大表格
	tableFooter?: (params?: any) => React.ReactNode; // 自定义表格底部
	tableTitle?: (params?: any) => React.ReactNode; // 自定义表格标题
	expandable?: Expandable; // 展开行配置
	isShowCustom?: boolean; // 是否显示自定义按钮
	bordered?: boolean; // 是否有边框
	virtual?: boolean; // 是否开启虚拟滚动 通过 virtual 开启虚拟滚动，此时 scroll.x 与 scroll.y 必须设置且为 number 类型。
	scrollX?: number | string; // 虚拟滚动x轴滚动条宽度
	scrollY?: number; // 虚拟滚动y轴滚动条高度
	onRow?: OnRowType<T>; // 行事件
	components?: TableComponents; // 自定义表格组件,用于编辑表格
	outLoading?: boolean; // 外部loading
}

// 表格组件的 ref 类型
interface ProTableRef<R extends object = any> {
	fetchData: (params?: R) => void;
}

// 表格组件
const ProTable = forwardRef(
	<T extends object = any, R extends object = any>(
		{ isPagination = true, tableSize = "middle", bordered = true, ...props }: ProTableProps<T>,
		ref: React.ForwardedRef<ProTableRef<R>>,
	) => {
		// 暴露给父组件的属性
		useImperativeHandle(ref, () => ({
			fetchData,
		}));
		// 表格hooks
		const {
			data,
			loading,
			tableParams,
			rowSelectionNew,
			selectedRowKeys,
			searchFormNew,
			handleTableChange,
			fetchData,
			searchParams,
			showSelectCustom,
			setShowSelectCustom,
			changeColumns,
			columnsNew,
		} = useTable<T, TableRowSelection<T>>({
			...props,
		});

		// 回调函数, 当数据发生变化时，调用回调函数,用于父组件获取子组件的属性和方法的
		useEffect(() => {
			if (props?.callback && typeof props?.callback === "function") {
				props?.callback({ data, selectedRowKeys, searchParams });
			}
		}, [props?.callback, data, selectedRowKeys, searchParams]);

		// 搜索表单提交
		const searchFinish = (values: any) => {
			fetchData(values);
		};

		const { styles } = useStyle();

		// 返回表格组件
		return (
			<div>
				{/* 搜索条件 */}
				{searchFormNew?.length && (
					<TableSearch searchForm={searchFormNew} formItemLayout={props?.formItemLayout} searchFinish={searchFinish} />
				)}
				{/* 表格统计自定义 */}
				{props?.tableRenderStatistics?.(searchParams)}
				{/* 表格头部 */}
				<TableHeader
					title={props?.title}
					tableHeaderRightSlot={props?.tableHeaderRightSlot}
					isShowCustom={props?.isShowCustom}
					setShowSelectCustom={setShowSelectCustom}
				/>
				{/* 表格 */}
				<Table<T>
					columns={columnsNew}
					rowKey={props?.rowKey}
					dataSource={data}
					rowSelection={rowSelectionNew}
					pagination={
						isPagination
							? {
									...tableParams.pagination,
									showTotal: (total, range) => `共${total}条，当前第${range[0]}-${range[1]}条`,
									showQuickJumper: true,
									showSizeChanger: true,
								}
							: false
					}
					size={tableSize}
					loading={props?.outLoading || loading}
					footer={props?.tableFooter}
					title={props?.tableTitle}
					bordered={bordered}
					expandable={props?.expandable}
					virtual={props?.virtual}
					className={styles.customTable}
					scroll={props?.virtual ? { x: props?.scrollX, y: props?.scrollY } : { x: props?.scrollX ?? "max-content" }}
					onChange={handleTableChange}
					onRow={props?.onRow}
					components={props?.components}
				/>
				{/* 自定义表格列 */}
				<CustomColumns
					showSelectCustom={showSelectCustom}
					setShowSelectCustom={setShowSelectCustom}
					columns={props?.columns}
					changeColumns={changeColumns}
				/>
			</div>
		);
	},
) as <T extends object = any, R extends object = any>(
	props: ProTableProps<T> & { ref?: React.Ref<ProTableRef<R>> },
) => React.ReactElement;
export default ProTable;
